﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Projektarbete.Popup;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Projektarbete
{
    class ChestPopup : PopupBase
    {
        protected Texture2D background;
        protected SpriteFont spriteFont;

        protected LinkedList<Rectangle> itemHitBoxes;
        protected LinkedList<Rectangle> inventoryItemHitBoxes;
        protected LinkedList<Rectangle> hitBoxes;
        protected LinkedList<PositionedString> positionedString;
        protected LinkedList<Button> buttons;

        protected Vector2 position;

        protected Item[][] contents;
        protected Item[][] inventoryContents;
        protected Item lastSelectedItem;
        protected Item inventoryLastSelectedItem;
        protected Item selectedItem;
        protected Item inventorySelectedItem;

        protected int itemScroll;
        protected int inventoryItemScroll;
        protected int textScroll;
        protected int inventoryTextScroll;
        protected int returnArrayLength;
        protected int inventoryReturnArrayLength;
        protected int compareTextIndex;

        protected string text;
        protected string inventoryText;
        protected string quickInfoText;
        protected string inventoryQuickInfoText;
        protected string[] compareText;

        protected Rectangle itemRectangle;
        protected Rectangle inventoryItemRectangle;
        protected Rectangle quickInfoRectangle;
        protected Rectangle inventoryQuickInfoRectangle;

        protected Texture2D white;

        protected bool locked;
        protected bool inventoryLocked;

        Vector2 tempVector2;
        Point tempPoint;

        //public VoidPointer UpdateContentsPointer;

        //TODO: Fix emptyTile text popping
        //TODO: FIX SCROLLING

        /// <summary>
        /// Creates a new InventoryPopup
        /// </summary>
        /// <param name="spriteFont">The font that should be used</param>
        /// <param name="background">The background image which sould be used</param>
        /// <param name="position">The position of the background image</param>
        public ChestPopup(SpriteFont spriteFont, Texture2D background, Vector2 position)
        {
            this.position = position;
            this.spriteFont = spriteFont;
            this.background = background;

            selectedItem = new ItemPresets.EmptySlot();
            inventorySelectedItem = new ItemPresets.EmptySlot();

            itemScroll = 0;
            inventoryItemScroll = 0;
            textScroll = 0;
            inventoryTextScroll = 0;
            returnArrayLength = 0;
            inventoryReturnArrayLength = 0;

            locked = false;
            inventoryLocked = false;

            itemRectangle = new Rectangle(80, 80, 280, 320);
            inventoryItemRectangle = new Rectangle(440, 80, 280, 320);
            quickInfoRectangle = new Rectangle(0, 0, 0, 0);
            inventoryQuickInfoRectangle = new Rectangle(0, 0, 0, 0);

            text = string.Empty;
            inventoryText = string.Empty;
            quickInfoText = string.Empty;
            inventoryQuickInfoText = string.Empty;

            positionedString = new LinkedList<PositionedString>();
            buttons = new LinkedList<Button>();

            hitBoxes = new LinkedList<Rectangle>();
            itemHitBoxes = new LinkedList<Rectangle>();
            inventoryItemHitBoxes = new LinkedList<Rectangle>();

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 7; x++)
                {
                    itemHitBoxes.AddLast(new Rectangle(80 + 40 * x, 80 + 40 * y, 40, 40));
                }
            }

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 7; x++)
                {
                    inventoryItemHitBoxes.AddLast(new Rectangle(440 + 40 * x, 80 + 40 * y, 40, 40));
                }
            }

            compareText = new string[] { "nothing", "name", "price", "size", "weight" };

            buttons.AddLast(new Button("Sort after ", new Vector2(70, 550), new VoidPointer(CycleSort), new Rectangle(70, 550, 200, 28)));

            tempVector2 = Vector2.Zero;
            tempPoint = Point.Zero;

            white = Global.White;
        }

        private void StoreItem()
        {
            if (inventorySelectedItem.getTexture != Global.ItemEmpty)
            {
                selectedItem = new ItemPresets.EmptySlot();
                PopupManager.StoreChestItem(inventorySelectedItem);
                inventoryQuickInfoText = string.Empty;
                inventoryLocked = false;
            }
        }

        private void TakeItem()
        {
            if (selectedItem.getTexture != Global.ItemEmpty)
            {
                if (PopupManager.TakeChestItem(selectedItem))
                {
                    selectedItem = new ItemPresets.EmptySlot();
                    quickInfoText = string.Empty;
                    locked = false;
                }
            }
        }

        private void CycleSort()
        {
            compareTextIndex++;

            if (compareTextIndex > compareText.Length - 1)
                compareTextIndex = 0;

            PopupManager.SortInventory(compareTextIndex);
        }

        public void UpdateContents(Item[][] contents, Item[][] inventoryContents)
        {
            if (contents.GetLength(0) < returnArrayLength)
                if (itemScroll == returnArrayLength - 8)
                    itemScroll--;

            if (inventoryContents.GetLength(0) < inventoryReturnArrayLength)
                if (inventoryItemScroll == inventoryReturnArrayLength - 8)
                    inventoryItemScroll--;

            returnArrayLength = contents.GetLength(0);
            inventoryReturnArrayLength = inventoryContents.GetLength(0);

            this.contents = contents;
            this.inventoryContents = inventoryContents;
        }

        /// <summary>
        /// Read input
        /// </summary>
        public override void Update()
        {
            int mouseWheelValue = Input.GetMouseWheelValueNormalized();
            int lastMouseWheelValue = Input.GetLastMouseWheelValueNormalized();

            Point mousePosition = Input.GetMousePosition();

            if (itemRectangle.Contains(mousePosition))
            {
                if (Input.IsKeyDown(Global.KeyConfig[5])) //[5] = modifyer key
                {
                    if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Up))
                        textScroll++;
                    else if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Down))
                        textScroll--;

                    if (mouseWheelValue != lastMouseWheelValue)
                        textScroll += (mouseWheelValue - lastMouseWheelValue) * 10;
                }
                else
                {
                    if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Up))
                    {
                        itemScroll--;
                        itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                    }
                    else if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Down))
                    {
                        itemScroll++;
                        itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                    }

                    if (mouseWheelValue != lastMouseWheelValue)
                    {
                        itemScroll += lastMouseWheelValue - mouseWheelValue;
                        itemScroll = (int)MathHelper.Clamp(itemScroll, 0, returnArrayLength - 8);
                    }

                    textScroll = (int)MathHelper.Clamp(textScroll, -(float)spriteFont.MeasureString(text).Y + 95, 0);
                }

                if (Input.IsNewMouseTwoPress())
                {
                    Point mousePositionAsArray = new Point((int)Math.Floor((double)mousePosition.X - 80) / 40, (int)Math.Floor((double)mousePosition.Y - 80) / 40);

                    selectedItem = contents[mousePositionAsArray.Y + itemScroll][mousePositionAsArray.X];
                    TakeItem();
                }

                if (Input.IsNewMouseOnePress())
                {
                    Point clickPosition = new Point((int)Math.Floor((double)mousePosition.X - 80) / 40, (int)Math.Floor((double)mousePosition.Y - 80) / 40);

                    clickPosition.X = (int)MathHelper.Clamp(clickPosition.X, 0, 6);
                    clickPosition.Y = (int)MathHelper.Clamp(clickPosition.Y, 0, 7);

                    Item clickedItem = contents[clickPosition.Y + itemScroll][clickPosition.X];

                    if (locked)
                    {
                        locked = false;
                        selectedItem = new ItemPresets.EmptySlot();
                    }
                    else
                        if (clickedItem.getTexture != Global.ItemEmpty)
                        {
                            locked = true;
                            selectedItem = clickedItem;

                            quickInfoRectangle = Rectangle.Empty;
                            quickInfoText = string.Empty;
                        }
                }

                if (!locked)
                {
                    tempPoint.X = (int)Math.Floor((double)mousePosition.X - 80) / 40;
                    tempPoint.Y = (int)Math.Floor((double)mousePosition.Y - 80) / 40;

                    Point clickPosition = tempPoint;

                    clickPosition.X = (int)MathHelper.Clamp(clickPosition.X, 0, 6);
                    clickPosition.Y = (int)MathHelper.Clamp(clickPosition.Y, 0, 7);

                    Item item = contents[clickPosition.Y + itemScroll][clickPosition.X];

                    if (item != lastSelectedItem)
                    {
                        text = Global.GetItemInfoToBoxText(item, 290);
                        quickInfoText = Global.GetItemInfoToQuickInfoRectangle(item);

                        if (quickInfoText == string.Empty)
                            quickInfoRectangle = Rectangle.Empty;
                        else
                        {
                            tempPoint.X = (int)spriteFont.MeasureString(quickInfoText).X;
                            tempPoint.Y = (int)spriteFont.MeasureString(quickInfoText).Y;

                            quickInfoRectangle = new Rectangle(mousePosition.X, mousePosition.Y, tempPoint.X, tempPoint.Y - 24);

                                if (mousePosition.Y + quickInfoRectangle.Height > itemRectangle.Bottom)
                                    quickInfoRectangle.Y = mousePosition.Y - quickInfoRectangle.Height;
                        }
                        

                        if (!Input.IsKeyDown(Global.KeyConfig[5]))
                            textScroll = 0;
                    }
                    else
                    {
                        quickInfoRectangle.Location = mousePosition;


                        if (mousePosition.Y + quickInfoRectangle.Height > itemRectangle.Bottom)
                            quickInfoRectangle.Y = mousePosition.Y - quickInfoRectangle.Height;

                    }
                    lastSelectedItem = item;
                }
            }
            else
            {
                if (!locked)
                {
                    quickInfoRectangle = Rectangle.Empty;
                    quickInfoText = string.Empty;

                    lastSelectedItem = new ItemPresets.EmptySlot();
                }
            }

            if (inventoryItemRectangle.Contains(mousePosition)) //################################################################\\
            {
                if (Input.IsKeyDown(Global.KeyConfig[5])) //[5] = modifyer key
                {
                    if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Up))
                        inventoryTextScroll++;
                    else if (Input.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Down))
                        inventoryTextScroll--;
                    
                    if (mouseWheelValue != lastMouseWheelValue)
                        inventoryTextScroll += (mouseWheelValue - lastMouseWheelValue) * 10;
                }
                else
                {
                    if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Up))
                    {
                        inventoryItemScroll--;
                        inventoryItemScroll = (int)MathHelper.Clamp(inventoryItemScroll, 0, inventoryReturnArrayLength - 8);
                    }
                    else if (Input.IsNewPress(Microsoft.Xna.Framework.Input.Keys.Down))
                    {
                        inventoryItemScroll++;
                        inventoryItemScroll = (int)MathHelper.Clamp(inventoryItemScroll, 0, inventoryReturnArrayLength - 8);
                    }

                    if (mouseWheelValue != lastMouseWheelValue)
                    {
                        inventoryItemScroll += lastMouseWheelValue - mouseWheelValue;
                        inventoryItemScroll = (int)MathHelper.Clamp(inventoryItemScroll, 0, inventoryReturnArrayLength - 8);
                    }

                    inventoryTextScroll = (int)MathHelper.Clamp(inventoryTextScroll, -(float)spriteFont.MeasureString(inventoryText).Y + 95, 0);
                }

                if (Input.IsNewMouseTwoPress())
                {
                    tempPoint.X = (int)Math.Floor((double)mousePosition.X - 440) / 40;
                    tempPoint.Y = (int)Math.Floor((double)mousePosition.Y - 80) / 40;

                    inventorySelectedItem = inventoryContents[tempPoint.Y + inventoryItemScroll][tempPoint.X];
                    StoreItem();
                }

                if (Input.IsNewMouseOnePress())
                {
                    tempPoint.X = (int)Math.Floor((double)mousePosition.X - 440) / 40;
                    tempPoint.Y = (int)Math.Floor((double)mousePosition.Y - 80) / 40;

                    tempPoint.X = (int)MathHelper.Clamp(tempPoint.X, 0, 6);
                    tempPoint.Y = (int)MathHelper.Clamp(tempPoint.Y, 0, 7);

                    Item inventoryClickedItem = inventoryContents[tempPoint.Y + inventoryItemScroll][tempPoint.X];

                    if (inventoryLocked)
                    {
                        inventoryLocked = false;
                        inventorySelectedItem = new ItemPresets.EmptySlot();
                    }
                    else
                        if (inventoryClickedItem.getTexture != Global.ItemEmpty)
                        {
                            inventoryLocked = true;
                            inventorySelectedItem = inventoryClickedItem;

                            inventoryQuickInfoRectangle = Rectangle.Empty;
                            inventoryQuickInfoText = string.Empty;
                        }
                }

                if (!inventoryLocked)
                {
                    tempPoint.X = (int)Math.Floor((double)mousePosition.X - 440) / 40;
                    tempPoint.Y = (int)Math.Floor((double)mousePosition.Y - 80) / 40;

                    tempPoint.X = (int)MathHelper.Clamp(tempPoint.X, 0, 6);
                    tempPoint.Y = (int)MathHelper.Clamp(tempPoint.Y, 0, 7);

                    Item item = inventoryContents[tempPoint.Y + inventoryItemScroll][tempPoint.X];

                    if (item != inventoryLastSelectedItem)
                    {
                        inventoryText = Global.GetItemInfoToBoxText(item, 290);
                        inventoryQuickInfoText = Global.GetItemInfoToQuickInfoRectangle(item);

                        if (inventoryQuickInfoText == string.Empty)
                            inventoryQuickInfoRectangle = Rectangle.Empty;
                        else
                        {
                            tempPoint.X = (int)spriteFont.MeasureString(inventoryQuickInfoText).X;
                            tempPoint.Y = (int)spriteFont.MeasureString(inventoryQuickInfoText).Y;

                            inventoryQuickInfoRectangle = new Rectangle(mousePosition.X - tempPoint.X, mousePosition.Y, tempPoint.X, tempPoint.Y - 24);

                            if (mousePosition.Y + inventoryQuickInfoRectangle.Height > itemRectangle.Bottom)
                                inventoryQuickInfoRectangle.Y = mousePosition.Y - inventoryQuickInfoRectangle.Height;
                        }

                        if (!Input.IsKeyDown(Global.KeyConfig[5]))
                            inventoryTextScroll = 0;
                    }
                    else
                    {
                        tempPoint.X = mousePosition.X - inventoryQuickInfoRectangle.Width;
                        tempPoint.Y = mousePosition.Y;
                        inventoryQuickInfoRectangle.Location = tempPoint;

                        if (mousePosition.Y + inventoryQuickInfoRectangle.Height > itemRectangle.Bottom)
                            inventoryQuickInfoRectangle.Y = mousePosition.Y - inventoryQuickInfoRectangle.Height;

                    }
                    inventoryLastSelectedItem = item;
                }
            }
            else
            {
                if (!inventoryLocked)
                {
                    inventoryQuickInfoRectangle = Rectangle.Empty;
                    inventoryQuickInfoText = string.Empty;

                    inventoryLastSelectedItem = new ItemPresets.EmptySlot();
                }

                if (Input.IsNewMouseOnePress())
                {
                    foreach (Button button in buttons)
                    {
                        if (button.hitbox.Contains(mousePosition))
                            button.Click();
                    }
                }
            }
        }
        /// <summary>
        /// Draws the entire popup
        /// </summary>
        /// <param name="spriteBatch"></param>
        /// <param name="graphicsDevice"></param>
        public override void Draw(SpriteBatch spriteBatch, GraphicsDevice graphicsDevice)
        {
            spriteBatch.Draw(background, position, Color.White);

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 7; x++)
                {
                    tempVector2.X = 82 + x * 35 + x * 5;
                    tempVector2.Y = 86 + y * 35 + y * 5;
                    spriteBatch.Draw(contents[y + itemScroll][x].getTexture, tempVector2, Color.White);
                }
            }

            for (int y = 0; y < 8; y++)
            {
                for (int x = 0; x < 7; x++)
                {
                    tempVector2.X = 442 + x * 35 + x * 5;
                    tempVector2.Y = 86 + y * 35 + y * 5;
                    spriteBatch.Draw(inventoryContents[y + inventoryItemScroll][x].getTexture, tempVector2, Color.White);
                }
            }

            foreach (PositionedString thisPositionedString in positionedString)
                spriteBatch.DrawString(spriteFont, thisPositionedString.text, thisPositionedString.position, Color.White);

            foreach (Button button in buttons)
                spriteBatch.DrawString(spriteFont, button.text, button.position, Color.White);

            spriteBatch.Draw(white, quickInfoRectangle, new Color(0, 0, 0) * 0.8f);
            spriteBatch.Draw(white, inventoryQuickInfoRectangle, new Color(0, 0, 0) * 0.8f);

            tempVector2.X = quickInfoRectangle.X;
            tempVector2.Y = quickInfoRectangle.Y;
            spriteBatch.DrawString(spriteFont, quickInfoText, tempVector2, Color.White);
            tempVector2.X = inventoryQuickInfoRectangle.X;
            tempVector2.Y = inventoryQuickInfoRectangle.Y;
            spriteBatch.DrawString(spriteFont, inventoryQuickInfoText, tempVector2, Color.White);

            spriteBatch.End();

            //Klipp ut allt som är utanför infoText rutan
            graphicsDevice.RasterizerState = new RasterizerState() { ScissorTestEnable = true };
            graphicsDevice.ScissorRectangle = new Rectangle(65, 445, 670, 90);

            spriteBatch.Begin(SpriteSortMode.BackToFront, null, null, null, graphicsDevice.RasterizerState);

            tempVector2.X = 443;
            tempVector2.Y = 440 + inventoryTextScroll;
            spriteBatch.DrawString(spriteFont, inventoryText, tempVector2, Color.White);
            tempVector2.X = 65;
            tempVector2.Y = 440 + inventoryTextScroll;
            spriteBatch.DrawString(spriteFont, text, tempVector2, Color.White);

            //spritebatch.End();
            //Do not add spriteBatch.end();
        }
    }
}
